using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using WPCoco.Graphics;

namespace WPCoco
{
    /// <summary>
    /// Gradient layer
    /// </summary>
    public class GradientLayer : AffineNode
    {
        public GradientLayer()
        {
            Width = Screen.Width; Height = Screen.Height;
            Anchor = Vector2.Zero;
        }

        Color startColor = Color.Red;

        public Color StartColor
        {
            get { return startColor; }
            set 
            { 
                startColor = value;
                updateColor = true;
            }
        }

        Color endColor = Color.Blue;

        public Color EndColor
        {
            get { return endColor; }
            set 
            { 
                endColor = value;
                updateColor = true;
            }
        }

        Vector2 alongVector = new Vector2(0, 1);

        public Vector2 AlongVector
        {
            get { return alongVector; }
            set 
            { 
                alongVector = value;
                updateColor = true;
            }
        }

        bool compressedInterpolation = false;

        public bool CompressedInterpolation
        {
            get { return compressedInterpolation; }
            set 
            { 
                compressedInterpolation = value;
                updateColor = true;
            }
        }

        Color[] colors = new Color[4];
        bool updateColor = true;


        void UpdateColor() 
        {
            if (!updateColor) return;
            updateColor = false;

            float h = alongVector.Length();
            if (h == 0) return;

            float c = (float)Math.Sqrt(2.0);

            Vector2 u = alongVector / h;

            if (compressedInterpolation)
            {
                float h2 = 1 / (Math.Abs(u.X) + Math.Abs(u.Y));
                u *= h2 * c; 
            }

            Color start = startColor;
            Color end = endColor;

            // (0, 0)
            colors[0].R = (byte)(end.R + (start.R - end.R) * ((c + u.X + u.Y) / (2.0f * c)));
            colors[0].G = (byte)(end.G + (start.G - end.G) * ((c + u.X + u.Y) / (2.0f * c)));
            colors[0].B = (byte)(end.B + (start.B - end.B) * ((c + u.X + u.Y) / (2.0f * c)));
            colors[0].A = (byte)(end.A + (start.A - end.A) * ((c + u.X + u.Y) / (2.0f * c)));
            // (1, 0)
            colors[1].R = (byte)(end.R + (start.R - end.R) * ((c - u.X + u.Y) / (2.0f * c)));
            colors[1].G = (byte)(end.G + (start.G - end.G) * ((c - u.X + u.Y) / (2.0f * c)));
            colors[1].B = (byte)(end.B + (start.B - end.B) * ((c - u.X + u.Y) / (2.0f * c)));
            colors[1].A = (byte)(end.A + (start.A - end.A) * ((c - u.X + u.Y) / (2.0f * c)));
            // (0, 1)
            colors[2].R = (byte)(end.R + (start.R - end.R) * ((c + u.X - u.Y) / (2.0f * c)));
            colors[2].G = (byte)(end.G + (start.G - end.G) * ((c + u.X - u.Y) / (2.0f * c)));
            colors[2].B = (byte)(end.B + (start.B - end.B) * ((c + u.X - u.Y) / (2.0f * c)));
            colors[2].A = (byte)(end.A + (start.A - end.A) * ((c + u.X - u.Y) / (2.0f * c)));
            // (1, 1)
            colors[3].R = (byte)(end.R + (start.R - end.R) * ((c - u.X - u.Y) / (2.0f * c)));
            colors[3].G = (byte)(end.G + (start.G - end.G) * ((c - u.X - u.Y) / (2.0f * c)));
            colors[3].B = (byte)(end.B + (start.B - end.B) * ((c - u.X - u.Y) / (2.0f * c)));
            colors[3].A = (byte)(end.A + (start.A - end.A) * ((c - u.X - u.Y) / (2.0f * c)));
        }

        public override void SelfDraw(GameTime gameTime)
        {
            if (updateColor)
                UpdateColor();
            GraphicPrimitives.WorldMatrix = WorldMatrix.Shared.CurrentMatrix;
            GraphicPrimitives.FillRectangleCornerColored(Vector2.Zero, new Vector2(Width, Height), colors);
        }

        
    }
}
